<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">
<html>
<title>Bloomberg Development Environment</title>
<html>
<pre>
// Copyright 2014-2023 Bloomberg Finance L.P.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// bmqt_sessionoptions.h                                              -*-C++-*-
#ifndef INCLUDED_BMQT_SESSIONOPTIONS
#define INCLUDED_BMQT_SESSIONOPTIONS

//@PURPOSE: Provide a value-semantic type to configure session with the broker.
//
//@CLASSES: bmqt::SessionOptions: options to configure a session with a
//  BlazingMQ broker.
//
//@DESCRIPTION: &#39;bmqt::SessionOptions&#39; provides a value-semantic type,
// &#39;SessionOptions&#39;, which is used to specify session-level configuration
// parameters.
//
// Most applications should not need to change the parameters for creating a
// &#39;Session&#39;; the default parameters are fine.
//
// The following parameters are supported:
//: o !brokerUri!:
//:      Address of the broker to connect to. Default is to connect to the
//:      broker on the local host on the default port (30114).  The format is
//:      &#39;tcp://&lt;host&gt;:port&#39;.  Host can be:
//:      o an explicit hostname or &#39;localhost&#39;
//:      o an ip, example 10.11.12.13
//:      o a DNS entry.  In this case, the client will resolve the list of
//:        addresses from that entry, and try to connect to one of them.
//:        When the connection with the host goes down, it will automatically
//:        immediately failover and reconnects to another entry from the
//:        address list.
//:      If the environment variable &#39;BMQ_BROKER_URI&#39; is set, then instances of
//:      &#39;bmqa::Session&#39; will ignore the &#39;brokerUri&#39; field from the provided
//:      &#39;SessionOptions&#39; and use the value from this environment variable
//:      instead.
//:
//: o !processNameOverride!:
//:      If not empty, use this value for the processName in the identity
//:      message (useful for scripted language bindings).  This field is used
//:      in the broker&#39;s logs to more easily identify the client&#39;s process.
//:
//: o !numProcessingThreads!:
//:      Number of threads to use for processing events. Default is 1. Note
//:      that this setting has an effect only if providing a
//:      &#39;SessionEventHandler&#39; to the session.
//:
//: o !blobBufferSize!:
//:      Size (in bytes) of the blob buffers to use. Default value is 4k.
//:
//: o !channelHighWatermark!:
//:      Size (in bytes) to use for write cache high watermark on the
//:      channel. Default value is 128MB. This value is set on the
//:      &#39;writeCacheHiWatermark&#39; of the &#39;btemt_ChannelPoolConfiguration&#39; object
//:      used by the session with the broker. Note that BlazingMQ reserves 4MB
//:      of this value for control message, so the actual watermark for data
//:      published is &#39;channelHighWatermark - 4MB&#39;.
//:
//: o !statsDumpInterval!:
//:      Interval (in seconds) at which to dump stats in the logs. Set to 0 to
//:      disable recurring dump of stats (final stats are always dumped at end
//:      of session). Default is 5min. The value must be a multiple of 30s, in
//:      the range [0s - 60min].
//:
//: o !connectTimeout!,
//: o !disconnetTimeout!,
//: o !openQueueTimeout!,
//: o !configureQueueTimeout!,
//: o !closeQueueTimeout!,
//:      Default timeout to use for various operations.
//:
//: o !eventQueueLowWatermark!,
//: o !eventQueueHighWatermark!,
//:      Parameters to configure the EventQueue notification watermarks
//:      thresholds. The EventQueue is the buffer of all incoming events from
//:      the broker (PUSH and ACK messages as well as session and queue
//:      operations result) pending being processed by the application code.  A
//:      warning (&#39;bmqt::SessionEventType::e_SLOWCONSUMER_HIGHWATERMARK&#39;) is
//:      emitted when the buffer reaches the &#39;highWatermark&#39; value, and a
//:      notification (&#39;bmqt::SessionEventType::e_SLOWCONSUMER_NORMAL&#39;) is
//:      sent when the buffer is back to the &#39;lowWatermark&#39;. The
//:      &#39;highWatermark&#39; typically would be reached in case of either a very
//:      slow consumer, causing events to accumulate in the buffer, or a huge
//:      burst of data. Setting the &#39;highWatermark&#39; to a high value should be
//:      done cautiously because it will potentially hide slowness of the
//:      consumer because of the enqueuing of PUSH events for a consumer, ACK
//:      events for a producer as well as all system events to the buffer
//:      (meaning that the messages may have a huge latency). Note, it is also
//:      recommended to have a reasonable distance between &#39;highWatermark&#39; and
//:      &#39;lowWatermark&#39; values to avoid a constant back and forth toggling of
//:      state resulting from push pop of events.
//:
//: o !hostHealthMonitor!:
//:      Optional instance of a class derived from &#39;bmqpi::HostHealthMonitor&#39;,
//:      responsible for notifying the &#39;Session&#39; when the health of the host
//:      machine has changed. A &#39;hostHealthMonitor&#39; must be specified, in order
//:      for queues opened through the session to suspend on unhealthy hosts.
//:
//: o !traceOptions!:
//:      Provides the `bmqpi::DTContext` and `bmqpi::DTTracer` objects required
//:      for integration with a Distributed Trace framework. If these objects
//:      are provided, then the session will use them to create &quot;spans&quot; to
//:      represent requests made to the BlazingMQ broker on behalf of
//:      operations initiated by the client. This includes session-level
//:      operations (e.g., Session-Start, Session-Stop) as well as queue-level
//:      operations (e.g., Queue-Open, Queue-Configure, Queue-Close).
//


// BMQ
#include &lt;bmqscm_version.h&gt;

// BDE
#include &lt;bdlt_timeunitratio.h&gt;
#include &lt;bsl_iosfwd.h&gt;
#include &lt;bsl_memory.h&gt;
#include &lt;bsl_string.h&gt;
#include &lt;bslma_allocator.h&gt;
#include &lt;bslma_usesbslmaallocator.h&gt;
#include &lt;bslmf_nestedtraitdeclaration.h&gt;
#include &lt;bsls_annotation.h&gt;
#include &lt;bsls_assert.h&gt;
#include &lt;bsls_timeinterval.h&gt;
#include &lt;bsls_types.h&gt;

namespace BloombergLP {

// FORWARD DECLARATIONS
namespace bmqpi { class DTContext; }
namespace bmqpi { class DTTracer; }
namespace bmqpi { class HostHealthMonitor; }

namespace bmqt {


                            // ====================
                            // class SessionOptions
                            // ====================

class SessionOptions {
    // value-semantic type for options to configure a session with a BlazingMQ
    // broker

  public:
    // CONSTANTS
    static const char k_BROKER_DEFAULT_URI[];
                      // Default URI of the &#39;bmqbrkr&#39; to connect to.

    static const int  k_BROKER_DEFAULT_PORT = 30114;
                      // Default port the &#39;bmqbrkr&#39; is listening to for client
                      // to connect.

    static const int  k_QUEUE_OPERATION_DEFAULT_TIMEOUT =
                                 5 * bdlt::TimeUnitRatio::k_SECONDS_PER_MINUTE;
                      // The default, and minimum recommended, value for queue
                      // operations (open, configure, close).

  private:
    // DATA
    bsl::string                               d_brokerUri;
                                        // URI of the broker to connect to (ex:
                                        // &#39;tcp://localhost:30114&#39;).  Default
                                        // is to connect to the local broker.

    bsl::string                               d_processNameOverride;
                                        // If not empty, use this value for the
                                        // processName in the identity message
                                        // (useful for scripted language
                                        // bindings).

    int                                       d_numProcessingThreads;
                                        // Number of processing threads.
                                        // Default is 1 thread.

    int                                       d_blobBufferSize;
                                        // Size of the blobs buffer.

    bsls::Types::Int64                        d_channelHighWatermark;
                                        // Write cache high watermark to use on
                                        // the channel

    bsls::TimeInterval                        d_statsDumpInterval;
                                        // Interval at which to dump stats to
                                        // log file (0 to disable dump)

    bsls::TimeInterval                        d_connectTimeout;

    bsls::TimeInterval                        d_disconnectTimeout;

    bsls::TimeInterval                        d_openQueueTimeout;

    bsls::TimeInterval                        d_configureQueueTimeout;

    bsls::TimeInterval                        d_closeQueueTimeout;
                                        // Timeout for operations of the
                                        // corresponding type.

    int                                       d_eventQueueLowWatermark;

    int                                       d_eventQueueHighWatermark;
                                        // Parameters to configure the
                                        // EventQueue.

    int                                       d_eventQueueSize;
                                        // DEPRECATED: This parameter is no
                                        // longer relevant and will be removed
                                        // in future release of libbmq.

    bsl::shared_ptr&lt;bmqpi::HostHealthMonitor&gt; d_hostHealthMonitor_sp;

    bsl::shared_ptr&lt;bmqpi::DTContext&gt;         d_dtContext_sp;
    bsl::shared_ptr&lt;bmqpi::DTTracer&gt;          d_dtTracer_sp;

  public:
     // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(SessionOptions, bslma::UsesBslmaAllocator)

    // CREATORS
    explicit SessionOptions(bslma::Allocator *allocator = 0);
        // Create a new SessionOptions using the optionally specified
        // &#39;allocator&#39;.

    SessionOptions(const SessionOptions&amp;  other,
                   bslma::Allocator      *allocator = 0);
        // Create a new SessionOptions by copying values from the specified
        // &#39;other&#39;, using the optionally specified &#39;allocator&#39;.

    // MANIPULATORS
    SessionOptions&amp; setBrokerUri(const bslstl::StringRef&amp; value);
        // Set the broker URI to the specified &#39;value&#39;.

    SessionOptions&amp;
    setProcessNameOverride(const bslstl::StringRef&amp; value);
        // Set an override of the proces name to the specified &#39;value&#39;.

    SessionOptions&amp; setNumProcessingThreads(int value);
        // Set the number of processing threads to the specified &#39;value&#39;.

    SessionOptions&amp; setBlobBufferSize(int value);
        // Set the specified &#39;value&#39; for the size of blobs buffers.

    SessionOptions&amp; setChannelHighWatermark(bsls::Types::Int64 value);
        // Set the specified &#39;value&#39; (in bytes) for the channel high
        // watermark.  The behavior is undefined unless
        // &#39;8 * 1024 * 1024 &lt; value&#39;.

    SessionOptions&amp; setStatsDumpInterval(const bsls::TimeInterval&amp; value);
        // Set the statsDumpInterval to the specified &#39;value&#39;. The behavior is
        // undefined unless &#39;value&#39; is a multiple of 30s and less than 60
        // minutes.

    SessionOptions&amp; setConnectTimeout(const bsls::TimeInterval&amp; value);
    SessionOptions&amp; setDisconnectTimeout(const bsls::TimeInterval&amp; value);
    SessionOptions&amp; setOpenQueueTimeout(const bsls::TimeInterval&amp; value);
    SessionOptions&amp; setConfigureQueueTimeout(const bsls::TimeInterval&amp; value);
    SessionOptions&amp; setCloseQueueTimeout(const bsls::TimeInterval&amp; value);
        // Set the timeout for operations of the corresponding type to the
        // specified &#39;value&#39;.

    SessionOptions&amp;
    setHostHealthMonitor(
                     const bsl::shared_ptr&lt;bmqpi::HostHealthMonitor&gt;&amp; monitor);
        // Set a &#39;HostHealthMonitor&#39; object that will notify the session when
        // the health of the host has changed.

    SessionOptions&amp;
    setTraceOptions(const bsl::shared_ptr&lt;bmqpi::DTContext&gt;&amp; dtContext,
                    const bsl::shared_ptr&lt;bmqpi::DTTracer&gt;&amp;  dtTracer);
        // Set the &#39;DTContext&#39; and &#39;DTTracer&#39; objects needed to integrate with
        // Distributed Trace frameworks. Either both arguments must point to
        // valid instances, or both must be empty shared_ptr&#39;s; if either is an
        // empty shared_ptr and the other is not, then behavior is undefined.

    SessionOptions&amp; configureEventQueue(int queueSize,
                                        int lowWatermark,
                                        int highWatermark);
        // DEPRECATED: Use &#39;configureEventQueue(int lowWatermark,
        //                                      int highWatermark)&#39;
        //             instead.  This method will be marked as
        //             &#39;BSLS_ANNOTATION_DEPRECATED&#39; in future release of
        //             libbmq.

    SessionOptions&amp; configureEventQueue(int lowWatermark, int highWatermark);
        // Configure the EventQueue notification watermarks thresholds with the
        // specified &#39;lowWatermark&#39; and &#39;highWatermark&#39; value.  Refer to the
        // component level documentation for explanation of those watermarks.
        // The behavior is undefined unless &#39;lowWatermark &lt; highWatermark&#39;.

    // ACCESSORS
    const bsl::string&amp; brokerUri() const;
        // Get the broker URI.

    const bsl::string&amp; processNameOverride() const;
        // Return the process name override.

    int numProcessingThreads() const;
        // Get the number of processing threads.

    int blobBufferSize() const;
        // Get the size of the blobs buffer.

    bsls::Types::Int64 channelHighWatermark() const;
        // Get the channel high watermark.

    const bsls::TimeInterval&amp; statsDumpInterval() const;
        // Get the stats dump interval.

    const bsls::TimeInterval&amp; connectTimeout() const;
    const bsls::TimeInterval&amp; disconnectTimeout() const;
    const bsls::TimeInterval&amp; openQueueTimeout() const;
    const bsls::TimeInterval&amp; configureQueueTimeout() const;
    const bsls::TimeInterval&amp; closeQueueTimeout() const;
        // Get the timeout for the operations of the corresponding type.

    const bsl::shared_ptr&lt;bmqpi::HostHealthMonitor&gt;&amp; hostHealthMonitor() const;

    const bsl::shared_ptr&lt;bmqpi::DTContext&gt;&amp; traceContext() const;
        // Get the Distributed Trace context object.

    const bsl::shared_ptr&lt;bmqpi::DTTracer&gt;&amp; tracer() const;
        // Get the Distributed Trace tracer object.

    int eventQueueLowWatermark() const;
    int eventQueueHighWatermark() const;

    int eventQueueSize() const;
        // DEPRECATED: This parameter is no longer relevant and will be removed
        // in future release of libbmq.

    bsl::ostream&amp; print(bsl::ostream&amp; stream,
                        int           level          = 0,
                        int           spacesPerLevel = 4) const;
        // Format this object to the specified output &#39;stream&#39; at the (absolute
        // value of) the optionally specified indentation &#39;level&#39; and return a
        // reference to &#39;stream&#39;.  If &#39;level&#39; is specified, optionally specify
        // &#39;spacesPerLevel&#39;, the number of spaces per indentation level for
        // this and all of its nested objects.  If &#39;level&#39; is negative,
        // suppress indentation of the first line.  If &#39;spacesPerLevel&#39; is
        // negative format the entire output on one line, suppressing all but
        // the initial indentation (as governed by &#39;level&#39;).  If &#39;stream&#39; is
        // not valid on entry, this operation has no effect.
};

// FREE OPERATORS
bool operator==(const SessionOptions&amp; lhs, const SessionOptions&amp; rhs);
    // Return &#39;true&#39; if the specified &#39;rhs&#39; object contains the value of the
    // same type as contained in the specified &#39;lhs&#39; object and the value
    // itself is the same in both objects, return false otherwise.

bool operator!=(const SessionOptions&amp; lhs, const SessionOptions&amp; rhs);
    // Return &#39;false&#39; if the specified &#39;rhs&#39; object contains the value of the
    // same type as contained in the specified &#39;lhs&#39; object and the value
    // itself is the same in both objects, return &#39;true&#39; otherwise.

bsl::ostream&amp; operator&lt;&lt;(bsl::ostream&amp; stream, const SessionOptions&amp; rhs);
    // Format the specified &#39;rhs&#39; to the specified output &#39;stream&#39; and return a
    // reference to the modifiable &#39;stream&#39;.


// ============================================================================
//                             INLINE DEFINITIONS
// ============================================================================


                            // --------------------
                            // class SessionOptions
                            // --------------------

// MANIPULATORS
inline
SessionOptions&amp;
SessionOptions::setBrokerUri(const bslstl::StringRef&amp; value)
{
    d_brokerUri.assign(value.data(), value.length());
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setProcessNameOverride(const bslstl::StringRef&amp; value)
{
    d_processNameOverride.assign(value.data(), value.length());
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setNumProcessingThreads(int value)
{
    d_numProcessingThreads = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setBlobBufferSize(int value)
{
    d_blobBufferSize = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setChannelHighWatermark(bsls::Types::Int64 value)
{
    // PRECONDITIONS
    BSLS_ASSERT_OPT(8 * 1024 * 1024 &lt; value);
        // We reserve 4MB for control message (see
        // &#39;bmqimp::BrokerSession::k_CONTROL_DATA_WATERMARK_EXTRA&#39;) so make
        // sure the provided value is greater than it.

    d_channelHighWatermark = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setStatsDumpInterval(const bsls::TimeInterval&amp; value)
{
    // PRECONDITIONS
    BSLS_ASSERT_OPT(    value.seconds() % 30 == 0
                    &amp;&amp; &quot;value must be a multiple of 30s&quot;);
    BSLS_ASSERT_OPT(     value.seconds()
                       &lt; bdlt::TimeUnitRatio::k_SECONDS_PER_HOUR
                    &amp;&amp; &quot;value must be &lt; 10 min&quot;);

    d_statsDumpInterval = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setConnectTimeout(const bsls::TimeInterval&amp; value)
{
    d_connectTimeout = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setDisconnectTimeout(const bsls::TimeInterval&amp; value)
{
    d_disconnectTimeout = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setOpenQueueTimeout(const bsls::TimeInterval&amp; value)
{
    d_openQueueTimeout = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setConfigureQueueTimeout(const bsls::TimeInterval&amp; value)
{
    d_configureQueueTimeout = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setCloseQueueTimeout(const bsls::TimeInterval&amp; value)
{
    d_closeQueueTimeout = value;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setHostHealthMonitor(
                      const bsl::shared_ptr&lt;bmqpi::HostHealthMonitor&gt;&amp; monitor)
{
    d_hostHealthMonitor_sp = monitor;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::setTraceOptions(
                              const bsl::shared_ptr&lt;bmqpi::DTContext&gt;&amp; context,
                              const bsl::shared_ptr&lt;bmqpi::DTTracer&gt;&amp;  tracer)
{
    BSLS_ASSERT_OPT((context &amp;&amp; tracer) || (!context &amp;&amp; !tracer));

    d_dtContext_sp = context;
    d_dtTracer_sp  = tracer;
    return *this;
}

inline
SessionOptions&amp;
SessionOptions::configureEventQueue(int queueSize,
                                    int lowWatermark,
                                    int highWatermark)
{
    d_eventQueueSize = queueSize;
    return configureEventQueue(lowWatermark, highWatermark);
}

inline
SessionOptions&amp;
SessionOptions::configureEventQueue(int lowWatermark,
                                    int highWatermark)
{
    // PRECONDITIONS
    BSLS_ASSERT_OPT(lowWatermark &lt; highWatermark);

    d_eventQueueLowWatermark  = lowWatermark;
    d_eventQueueHighWatermark = highWatermark;

    return *this;
}

// ACCESSORS
inline
const bsl::string&amp;
SessionOptions::brokerUri() const
{
    return d_brokerUri;
}

inline
const bsl::string&amp;
SessionOptions::processNameOverride() const
{
    return d_processNameOverride;
}

inline
int
SessionOptions::numProcessingThreads() const
{
    return d_numProcessingThreads;
}

inline
int
SessionOptions::blobBufferSize() const
{
    return d_blobBufferSize;
}

inline
bsls::Types::Int64
SessionOptions::channelHighWatermark() const
{
    return d_channelHighWatermark;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::statsDumpInterval() const
{
    return d_statsDumpInterval;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::connectTimeout() const
{
    return d_connectTimeout;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::disconnectTimeout() const
{
    return d_disconnectTimeout;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::openQueueTimeout() const
{
    return d_openQueueTimeout;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::configureQueueTimeout() const
{
    return d_configureQueueTimeout;
}

inline
const bsls::TimeInterval&amp;
SessionOptions::closeQueueTimeout() const
{
    return d_closeQueueTimeout;
}

inline
const bsl::shared_ptr&lt;bmqpi::HostHealthMonitor&gt;&amp;
SessionOptions::hostHealthMonitor() const
{
    return d_hostHealthMonitor_sp;
}

inline
const bsl::shared_ptr&lt;bmqpi::DTContext&gt;&amp;
SessionOptions::traceContext() const
{
    return d_dtContext_sp;
}

inline
const bsl::shared_ptr&lt;bmqpi::DTTracer&gt;&amp;
SessionOptions::tracer() const
{
    return d_dtTracer_sp;
}

inline
int
SessionOptions::eventQueueLowWatermark() const
{
    return d_eventQueueLowWatermark;
}

inline
int
SessionOptions::eventQueueHighWatermark() const
{
    return d_eventQueueHighWatermark;
}

inline
int
SessionOptions::eventQueueSize() const
{
    return d_eventQueueSize;
}

}  // close package namespace

                            // --------------------
                            // class SessionOptions
                            // --------------------

inline
bool
bmqt::operator==(const bmqt::SessionOptions&amp; lhs,
                 const bmqt::SessionOptions&amp; rhs)
{
    return    lhs.brokerUri()               == rhs.brokerUri()
           &amp;&amp; lhs.numProcessingThreads()    == rhs.numProcessingThreads()
           &amp;&amp; lhs.blobBufferSize()          == rhs.blobBufferSize()
           &amp;&amp; lhs.channelHighWatermark()    == rhs.channelHighWatermark()
           &amp;&amp; lhs.statsDumpInterval()       == rhs.statsDumpInterval()
           &amp;&amp; lhs.connectTimeout()          == rhs.connectTimeout()
           &amp;&amp; lhs.openQueueTimeout()        == rhs.openQueueTimeout()
           &amp;&amp; lhs.configureQueueTimeout()   == rhs.configureQueueTimeout()
           &amp;&amp; lhs.closeQueueTimeout()       == rhs.closeQueueTimeout()
           &amp;&amp; lhs.eventQueueLowWatermark()  == rhs.eventQueueLowWatermark()
           &amp;&amp; lhs.eventQueueHighWatermark() == rhs.eventQueueHighWatermark()
           &amp;&amp; lhs.hostHealthMonitor()       == rhs.hostHealthMonitor()
           &amp;&amp; lhs.traceContext()            == rhs.traceContext()
           &amp;&amp; lhs.tracer()                  == rhs.tracer();
}

inline
bool
bmqt::operator!=(const bmqt::SessionOptions&amp; lhs,
                 const bmqt::SessionOptions&amp; rhs)
{
    return    lhs.brokerUri()               != rhs.brokerUri()
           || lhs.numProcessingThreads()    != rhs.numProcessingThreads()
           || lhs.blobBufferSize()          != rhs.blobBufferSize()
           || lhs.channelHighWatermark()    != rhs.channelHighWatermark()
           || lhs.statsDumpInterval()       != rhs.statsDumpInterval()
           || lhs.connectTimeout()          != rhs.connectTimeout()
           || lhs.openQueueTimeout()        != rhs.openQueueTimeout()
           || lhs.configureQueueTimeout()   != rhs.configureQueueTimeout()
           || lhs.closeQueueTimeout()       != rhs.closeQueueTimeout()
           || lhs.eventQueueLowWatermark()  != rhs.eventQueueLowWatermark()
           || lhs.eventQueueHighWatermark() != rhs.eventQueueHighWatermark()
           || lhs.hostHealthMonitor()       != rhs.hostHealthMonitor()
           || lhs.traceContext()            != rhs.traceContext()
           || lhs.tracer()                  != rhs.tracer();
}

inline
bsl::ostream&amp;
bmqt::operator&lt;&lt;(bsl::ostream&amp;               stream,
                 const bmqt::SessionOptions&amp; rhs)
{
    return rhs.print(stream, 0, -1);
}

}  // close enterprise namespace

#endif
</pre>
</body>
</html>
